/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufpb.projetoesa.negocio;

import br.ufpb.projetoesa.exceptions.CursoInexistenteException;
import br.ufpb.projetoesa.exceptions.CursoInvalidoException;
import br.ufpb.projetoesa.exceptions.DisciplinaInexistenteException;
import br.ufpb.projetoesa.exceptions.DisciplinaInvalidaException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author leonardo
 */
public class Centro {
    
    private String nome;
    private String endereco;
    private String diretor;
    private List<Curso> cursos;
    private List<Disciplina> disciplinas;
    
    
    public Centro(String nome){
        this(nome, "sem endereco");
    }
    
    public Centro(String nome, String end){
        this(nome, end, "sem diretor");
    }
    
    public Centro(String nome, String end, String dir){
        this.nome = nome;
        this.endereco = end;
        this.diretor = dir;
        cursos = new ArrayList<Curso>();
        disciplinas = new ArrayList<Disciplina>();
    }
    
    
    
    public void addDisciplina(String id, String nome) throws DisciplinaInvalidaException {
        addDisciplina(id, nome, 0);
    }
    
   
    public void addDisciplina(String id, String nome, int creditos) throws DisciplinaInvalidaException {
        if (id != null && nome != null) {
            Disciplina d = new Disciplina(id, nome, creditos);
            addDisciplina(d);
        } else {
            throw new DisciplinaInvalidaException("Ocorreu um erro ao tentar cadastrar uma nova Disciplina neste Centro.");
        }
    }
    
    
    public void addDisciplina(Disciplina d) throws DisciplinaInvalidaException {
        if (d != null)
            disciplinas.add(d);
    }
    
    
    /**
     * Remove uma disciplina de um curso através da sua identificação.
     * Esse método pesquisa a disciplina contida no curso e repassa
     * para o método removerDisciplinaDeUmCurso que já recebe a própria
     * Disciplina a ser removida.
     */
    public void removeDisciplinaDeUmCurso(Curso curso, String id) throws CursoInexistenteException, 
            DisciplinaInexistenteException{
        
        removeDisciplinaDeUmCurso(curso, id);
    }
    
    /**
     * Remove esta Disciplina deste Curso.
     */
    public void removeDisciplinaDeUmCurso(Curso curso, Disciplina disc) throws CursoInexistenteException, 
           DisciplinaInexistenteException {
        if (this.cursos.contains(curso)) {
            curso.removerDisciplina(disc);
        } else {
            throw new CursoInexistenteException("Esse Curso não está cadastrado neste Centro.");
        }
        
    }
    
    /**
     * Localiza o Curso pelo idCurso e a Disciplina pelo idDisc e invoca
     * outro método desta classe para realizar a tarefa.
     */
    public void removeDisciplinaDeUmCurso(String idCurso, String idDisc) throws CursoInexistenteException,
            DisciplinaInexistenteException {
        
        Curso c = getCurso(idCurso);
        removeDisciplinaDeUmCurso(c, c.getDisciplinaID(idDisc));
        
    }
    
    
    /**
     * Remove esta Disciplina do Curso que contém essa identificação (idCurso).
     */
    public void removeDisciplinaDeUmCurso(String idCurso, Disciplina disc) throws CursoInexistenteException,
            DisciplinaInexistenteException {
        
        removeDisciplinaDeUmCurso(getCurso(idCurso), disc);
        
    }
    
    
    /**
     * Retorna um curso cadastrado de acordo com a sua identificação,
     * se não houver, lança uma exceção.
     */
    public Curso getCurso(String id) throws CursoInexistenteException{
        
        for (Curso c: this.cursos){            
            if (c.getCursoID().equals(id)){
                return c;
            }            
        }
        throw new CursoInexistenteException("Não existe curso com essa identificação.");
    }

    /**
     * Remove um curso deste Centro. Caso não esteja cadastrado ou receba
     * um curso inexistente, será lançada uma exceção.
     */    
    public void removeCurso(Curso c) throws CursoInvalidoException, CursoInexistenteException {
        if (c != null){
            if (cursos.contains(c))
                cursos.remove(c);
            else
                throw new CursoInexistenteException("O curso " + c.getNomeCurso() + " não foi encontrado. \n"
                        + "Portanto, verifique os dados e tente novamente.");
        } else {
            throw new CursoInvalidoException("Ocorreu um erro ao tentar remover o curso. \n"
                    + "Verifique e tente novamente.");
        }
    }
    
    /**
     * Remove um curso deste Centro a partir do seu ID. Caso não esteja cadastrado ou receba
     * um curso inexistente, será lançada uma exceção.
     */    
    public void removeCurso(String id) throws CursoInvalidoException, CursoInexistenteException {
        if (id != null){
            for(Curso c: this.cursos){
                if (c.getCursoID().equals(id)){
                    cursos.remove(c);
                    return;
                }                    
            }
            throw new CursoInexistenteException("O curso com o ID: " + id + " não foi encontrado. \n"
                        + "Portanto, verifique os dados e tente novamente.");
        } else {
            throw new CursoInvalidoException("Ocorreu um erro ao tentar remover o curso. \n"
                    + "Verifique e tente novamente.");
        }
    }
    
    /**
     * Adiciona um novo curso a este Centro
     */
    public void addCurso(Curso c) throws CursoInvalidoException {
        if (c != null)
            cursos.add(c);
        else
            throw new CursoInvalidoException("Ocorreu um erro ao tentar cadastrar o curso. Verifique\n"
                    + "os parâmetros de entrada e tente novamente.");
    }
    
    
    /**
     * Adiciona um novo curso a este Centro
     */
    public void addCurso(String id, String nome) throws CursoInvalidoException {
        if (id != null && nome != null){
            Curso c = new Curso(id, nome);
            this.cursos.add(c);
        } else {
            throw new CursoInvalidoException("Ocorreu um erro ao tentar cadastrar o curso. Verifique\n"
                    + "os parâmetros de entrada e tente novamente.");
        }
    }
    
    
    /**
     * Adiciona um novo curso a este Centro
     */
    public void addCurso(String id, String nome, int cargaHoraria) throws CursoInvalidoException {
        if (id != null && nome != null){
            Curso c = new Curso(id, nome, cargaHoraria);
            this.cursos.add(c);
        } else {
            throw new CursoInvalidoException("Ocorreu um erro ao tentar cadastrar o curso. Verifique\n"
                    + "os parâmetros de entrada e tente novamente.");
        }
    }
    
    /**
     * Atualiza um Curso cadastrado neste Centro. Este método recebe um Curso
     * já cadastrado (a ser modificado) e uma nova instancia para o Curso
     * atualizado que será adicionado na lista de cursos.
     */
    public void atualizaCurso(Curso c1, Curso c2) throws CursoInvalidoException, 
            CursoInexistenteException {
        if (c1 != null && c2 != null){
            if (cursos.contains(c1)){
                cursos.remove(c1);
                cursos.add(c2);
            } else {
                throw new CursoInexistenteException("O curso " + c1.getNomeCurso() + " não foi encontrado. \n"
                        + "Portanto, verifique os dados e tente novamente.");
            }
        } else {
            throw new CursoInvalidoException("Ocorreu um erro ao tentar remover o curso. \n"
                    + "Verifique e tente novamente.");
        }
    }
    
    
    public List<Disciplina> getDisciplinas(){
        return this.disciplinas;
    }
    
    /**
     * Retorna todos os cursos cadastrados neste Centro.
     */
    public List<Curso> getCursos(){
        return this.cursos;
    }
    
    
    
    public String getDiretor() {
        return diretor;
    }

    public void setDiretor(String diretor) {
        this.diretor = diretor;
    }

    public String getEndereco() {
        return endereco;
    }

    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public List<Disciplina> pesquisaDisciplina(String nome){
        List<Disciplina> resultado = new ArrayList<Disciplina>();
        for(Disciplina d: this.disciplinas){
            if (d.getNome().toUpperCase().startsWith(nome.toUpperCase())){
                resultado.add(d);
            }
        }
        return resultado;
}
    
}